home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / ARexxTools / ScionRexx.lha / Scion2GEDCOM.rexx < prev    next >
Encoding:
OS/2 REXX Batch file  |  1995-11-17  |  21.9 KB  |  725 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  * $VER: Scion2GEDCOM 2.22 (17 Nov 1995)
  4.  *                                                                          *
  5.  *                      Written by Freddy Ariës                             *
  6.  * Address: Lindeboomweg 7, NL-7135 KE Harreveld, The Netherlands.          *
  7.  *                                                                          *
  8.  * This program was created to export the Scion data into the GEDCOM file   *
  9.  * format. It should work pretty good by now, although no guarantees        *
  10.  * whatsoever can be given. If you have any problems using this script,     *
  11.  * please describe them to me, as detailed as possible (and please also     *
  12.  * tell me what program you are using to read the GEDCOM file), then I will *
  13.  * try to work out a solution.                                              *
  14.  *                                                                          *
  15.  * GEDCOM was developed by the Family History Department of the Church of   *
  16.  * Jesus Christ of Latter-day Saints to provide a flexible uniform format   *
  17.  * for exchanging computerized genealogical data.  GEDCOM is an acronym for *
  18.  * GEnealogical Data COMmunication.  GEDCOM is provided to foster the       *
  19.  * sharing of genealogical information and the development of a wide range  *
  20.  * of inter-operable software products to assist genealogists, historians,  *
  21.  * and other researchers.                                                   *
  22.  *                                                                          *
  23.  * + SCION must be running for this AREXX script to work.                   *
  24.  * + This script uses (by default) the rexxreqtools.library (which requires *
  25.  *   a version of reqtools larger than 2.0 and rexxsyslib.library)          *
  26.  *   If you do not have these, run SetDefaults.rexx to change the settings. *
  27.  * + Dates should be in English, and in the format "DD MMM YYYY" or         *
  28.  *   "DD-MMM-YYYY", if you don't want any problems with programs importing  *
  29.  *   the GEDCOM data.                                                       *
  30.  *   If the dates in your database are not in English, please run the       *
  31.  *   Translate.rexx script first!                                           *
  32.  *                                                                          *
  33.  * DONE: - Progress indicator, using rexxarplib.library (requested by       *
  34.  *         Robbie J. Akins himself).                                        *
  35.  *       - Creation of QUAY value for date and place fields ending with '?' *
  36.  *       - Output of Scion's external note files to GEDCOM comment lines    *
  37.  *         (option)                                                         *
  38.  *       - Reference field is now output to GEDCOM's SOUR structure.        *
  39.  *       - Export of Celebrant and Witness fields, as well as Endreasons    *
  40.  *         'None' and 'Death' (temporary solution; experimental, until I    *
  41.  *         find a better way to do it). If any of these fields is           *
  42.  *         misinterpreted by your system, then please report this.          *
  43.  *       - Now uses preference file for default settings                    *
  44.  *                                                                          *
  45.  * TO DO (but low priority, unless someone really wants this[?]):           *
  46.  *  - Add Shell options for processing of Note files                        *
  47.  *  - Add support for other character sets (now Amiga extended ASCII codes  *
  48.  *    are assumed, even though the GEDCOM format specifies the ANSEL codes  *
  49.  *    as the default)                                                       *
  50.  *  - Maybe some kind of limited export facility                            *
  51.  *  - Suggestions, comments, bugreports, donations, etc. are appreciated.   *
  52.  *                                                                          *
  53.  ****************************************************************************/
  54.  
  55. options failat 20; options results
  56. arg outname outval
  57.  
  58. versionstr = "2.22"
  59.  
  60. /* Don't change the settings here! Run SetDefaults.rexx instead! */
  61. usereq = 1; prgrs = 1; pgopen = 0
  62. outp = 1; output = stdout; scrdev = stdout
  63. notesdir = ""
  64. PSCR = "SCIONGEN"
  65.  
  66. scrname = "CON:0//639//Scion Output/AUTO/SCREEN"
  67. incnote = 0;    /* include external note files */
  68. NL = '0A'x
  69.  
  70. signal on IOERR
  71.  
  72. do while outname = '?'
  73.   writeln(stdout, "OUTFILE/A,QUIET/S,NOREQ/S")
  74.   pull outname outval
  75. end
  76.  
  77. /* read preferences file */
  78.  
  79. if open(pfile, 'ENV:Scion/ScionRexx.prefs', 'r') then do
  80.   do while ~eof(pfile)
  81.     inln = readln(pfile)
  82.     if inln ~= "" then do
  83.       wstr = upper(word(inln, 1))
  84.       if wstr = "NOTES" then
  85.         notesdir = strip(delstr(inln, 1, length(wstr)), 'b', ' "')
  86.       else if wstr = "USEREQ" then
  87.         usereq = 1
  88.       else if wstr = "NOUSEREQ" then
  89.         usereq = 0
  90.       else if wstr = "PROGRESS" then
  91.         prgrs = 1
  92.       else if wstr = "NOPROGRESS" then
  93.         prgrs = 0
  94.       else if wstr = "PUBSCREEN" then
  95.         pscr = strip(delstr(inln, 1, length(wstr)), 'b', ' "')
  96.     end
  97.   end
  98.   close(pfile)
  99. end
  100.  
  101. if pscr = "" | (pscr ~= "WORKBENCH" & ~show('p', pscr)) then
  102.   pscr = "SCIONGEN"
  103. wstr = right(notesdir, 1)
  104. if wstr ~= '/' & wstr ~= ':' then notesdir = ""
  105. scrname = scrname||pscr
  106.  
  107. /* parse command line options, to enable calling the script automatically,
  108.  * eg. from a function key. This gets priority over global settings!
  109.  */
  110.  
  111. if outname ~= "" then do
  112.   if outname = "QUIET" | outname = "NOREQ" then do
  113.     outval = outname; outname = ""
  114.   end
  115. end
  116.  
  117. if outval = "QUIET" then do
  118.   outp = 0; usereq = 0; prgrs = 0
  119. end
  120. else if outval = "NOREQ" then do
  121.   usereq = 0; prgrs = 0
  122. end
  123.  
  124. if usereq & ~show('l','rexxreqtools.library') then do
  125.   if exists('libs:rexxreqtools.library') then
  126.     call addlib('rexxreqtools.library',0,-30,0)
  127.   else do
  128.     usereq = 0; outp = 1
  129.     Tell("Unable to open rexxreqtools.library - using text output")
  130.   end
  131. end
  132.  
  133. if ~usereq then prgrs = 0
  134.  
  135. if prgrs & ~show('l','rexxarplib.library') then do
  136.   if exists('libs:rexxarplib.library') then
  137.     call addlib('rexxarplib.library',0,-30,0)
  138.   else
  139.     prgrs = 0
  140. end
  141.  
  142. screentofront(pscr)
  143.  
  144. /* Originally stolen from Peter Billing - thanks Peter ;-) */
  145. if ~show('P','SCIONGEN') then do
  146.   EndString('I am sorry to say that the SCION Genealogist' || NL ||,
  147.     'database is not available. Please start the' || NL ||,
  148.     'SCION program BEFORE using this script!')
  149. end
  150.  
  151. MyPort = "SCIONGEN"
  152. Address value MyPort
  153. GETDBNAME
  154. dbname = upper(RESULT)
  155.  
  156. if outp & ~usereq then do
  157.   if pscr ~= "WORKBENCH" then do
  158.     scrdev = 'SCNS2GSCR'
  159.     if ~open(scrdev, scrname, 'w') then scrdev = stdout
  160.   end
  161.   Tell("Scion to GEDCOM conversion script v"||versionstr||" by Freddy Ariës")
  162.   Tell("Database: "||dbname)
  163.   Tell("(Make sure the date fields are in English!)"|| NL)
  164. end
  165.  
  166. /* It may be a good habit to add the ".scion" extension */
  167. /* to Scion database files */
  168. dblen = length(dbname)
  169. if dblen>6 & right(dbname, 6)=".SCION" then dbname=left(dbname, dblen - 6)
  170.  
  171. if outname = "" then do
  172.   if outp then do
  173.     if usereq then do
  174.       odev = rtezrequest('Current Scion database: '||dbname||NL||,
  175.        '(Make sure the date fields are in English!)'||NL||NL||,
  176.        'Where should the GEDCOM output be sent to?'||,
  177.        '',' _File |_Printer|_Screen|_Nowhere','Scion to GEDCOM v'||versionstr||' by Freddy Ariës','rt_pubscrname = '||PSCR)
  178.       select
  179.         when odev = 1 then do
  180.           /* We need a file requester for further data */
  181.           outname = rtfilerequest(,dbname||'.GED','Output filename',,'rt_pubscrname = '||PSCR||'   rtfi_initialpath = RAM:',)
  182.           if outname = '' then
  183.             outname = dbname||'.GED'
  184.         end
  185.         when odev = 2 then
  186.           outname = 'PRT:'
  187.         when odev = 3 then
  188.           outname = 'STDOUT'
  189.         otherwise
  190.           EndString("Aborted.")
  191.           /* You selected 'Nowhere' */
  192.       end
  193.     end
  194.     else do
  195.       Tell("Enter output file (filename with complete path, or PRT: for printer,")
  196.       TellNN("or STDOUT for screen): ")
  197.       outname = readln(scrdev)
  198.       outname = strip(outname, 'b', ' "')
  199.       Tell("Destination: "||outname)
  200.       TellNN("Continue (y/n)? ")
  201.       conf = readln(scrdev)
  202.       conf = upper(left(conf, 1))
  203.       /* Note that left works on empty strings ("") too! */
  204.       if conf ~= "Y" then EndString("Aborted.")
  205.       Tell("")
  206.     end
  207.   end
  208.   else
  209.     outname = "RAM:"dbname".GED"
  210.     /* If we're not allowed to use stdout, default to this filename */
  211. end
  212.  
  213. if outp then do
  214.   if usereq then do
  215.     incnote = rtezrequest("Include Scion's external Note files "||,
  216.         NL||"in GEDCOM comment lines?"||,
  217.         '',' _Yes| _No ','Input Request:','rt_pubscrname = '||PSCR)
  218.     if incnote & notesdir = "" then do
  219.       GETDBPATH
  220.       dbpath = RESULT
  221.       notesdir = rtfilerequest(,,'Select Scion Notes Directory:','_Ok','rt_pubscrname = '||PSCR||'   rtfi_flags = freqf_nofiles   rtfi_initialpath = '||dbpath,fres)
  222.       if fres = 0 then incnote = 0
  223.         /* User cancelled requester: external note files are not used */
  224.     end
  225.   end
  226.   else do
  227.     Tell("Include Scion's external Note files in GEDCOM comment lines?")
  228.     TellNN("(y/n) : ")
  229.     ptmp = readln(scrdev)
  230.     ptmp = upper(left(ptmp, 1))
  231.     if ptmp = "Y" then incnote = 1
  232.     else incnote = 0
  233.     if incnote & notesdir = "" then do
  234.       ptmp = ""
  235.       do until ptmp = ":" | ptmp = "/"
  236.         Tell("Enter full directory name where Scion's note files are located.")
  237.         TellNN("(MUST end with ':' or '/'): ")
  238.         pname = readln(scrdev)
  239.         pname = strip(pname, 'b', ' "')
  240.         ptmp = right(pname, 1)
  241.       end
  242.       notesdir = pname
  243.     end
  244.   end
  245. end
  246.  
  247. if outname ~= "STDOUT" then do
  248.   output = 'OUTPUT'
  249.   if ~open(output, outname, "w") then
  250.     EndString("ERROR: Unable to open output file.")
  251. end
  252. else
  253.   output = scrdev
  254.  
  255. if ~usereq then
  256.   Tell("Be patient - this may take a while...")
  257.  
  258. GETPROGVERSION
  259. prgvers = RESULT
  260.  
  261. writeln(output, "0 HEAD")
  262. writeln(output, "1 SOUR SCION_AMIGA")
  263. writeln(output, "2 NAME Scion Genealogist")
  264. writeln(output, "2 VERS "||prgvers)
  265. writeln(output, "2 CORP Robbie J. Akins")
  266. writeln(output, "3 ADDR 5 Austin Street, Wellington 6001, New Zealand")
  267.  
  268. str = "1 DATE" upper(date())
  269. writeln(output, str)
  270. str = "1 FILE" dbname
  271. writeln(output, str)
  272. writeln(output, "1 GEDC")
  273. writeln(output, "2 VERS 5.3")
  274. writeln(output, "1 CHAR AMIGA"); /* 8-bit extended ASCII, Amiga format */
  275. /*
  276.   TO DO:
  277.   Ask if destination is Ancestral File (LDS).  If so, ask for
  278.     Name (1), Address (3; mandatory), Phone (1) and Notes (3) data
  279.     and output the following lines:
  280.   writeln(output, "1 DEST ANSTFILE")
  281.   writeln(output, "1 SUBM @S1@")
  282.   writeln(output, "0 @S1@ SUBM")
  283.   writeln(output, "1 NAME <submitter name>"); --- mandatory
  284.   writeln(output, "2 NOTE <submitter note>")
  285.   writeln(output, "3 CONT <submitter note>")
  286.   writeln(output, "3 CONT <submitter note>")
  287.   writeln(output, "1 ADDR <submitter address>"); -- mandatory!
  288.   writeln(output, "2 CONT <submitter address>"); -- mandatory!
  289.   writeln(output, "2 CONT <submitter address>"); -- mandatory!
  290.   writeln(output, "2 PHON <submitter phone number>")
  291.  */
  292.  
  293. if prgrs then do
  294.   Postmsg(10, 10, "Scion to GEDCOM (by Freddy Ariës)\Database: "||dbname||"\Processing person:\ ", ""||PSCR"")
  295.   pgopen = 1
  296. end
  297.  
  298. GETTOTALIRN
  299. TotalIRN = RESULT
  300. do i = 1 to TotalIRN
  301.   if pgopen then Postmsg(,,"\\\"||i||" (of "||TotalIRN||")", PSCR)
  302.   EXISTPERSON i
  303.   if RESULT = 'YES' then
  304.   do
  305.     str = "0 @I"i"@ INDI"
  306.     writeln(output, str)
  307.     GETFIRSTNAME i
  308.     fnames = RESULT
  309.     fnames = translate(fnames, ';', '/')
  310.     /* Fixed since v2.13: no '/' characters allowed in GEDCOM namestring! */
  311.     GETLASTNAME i
  312.     lname = RESULT
  313.     lname = translate(lname, ';', '/')
  314.     str = "1 NAME "fnames"/"lname"/"
  315.     writeln(output, str)
  316.     GETSEX i
  317.     sx = RESULT
  318.     if sx ~= "M" then do
  319.      sx = "F"
  320.     end
  321.     str = "1 SEX" sx
  322.     writeln(output, str)
  323.     GETBIRTHDATE i
  324.     datestr = ParseDate(upper(RESULT))
  325.     GETBIRTHPLACE i
  326.     placestr = RESULT
  327.     if datestr ~= "" | placestr ~= "" then do
  328.       writeln(output, "1 BIRT")
  329.       DoOutputDate(datestr, output)
  330.       DoOutputPlace(placestr, output)
  331.     end
  332.     GETBAPTISMDATE i
  333.     datestr = ParseDate(upper(RESULT))
  334.     GETBAPTISMPLACE i
  335.     placestr = RESULT
  336.     if datestr ~= "" | placestr ~= "" then do
  337.       writeln(output, "1 BAPM")
  338.       DoOutputDate(datestr, output)
  339.       DoOutputPlace(placestr, output)
  340.     end
  341.     GETDEATHDATE i
  342.     datestr = ParseDate(RESULT)
  343.     GETDEATHPLACE i
  344.     placestr = RESULT
  345.     GETDIEDOF i
  346.     diedofstr = RESULT
  347.     if datestr ~= "" | placestr ~= "" | diedofstr ~= "" then do
  348.       writeln(output, "1 DEAT")
  349.       DoOutputDate(datestr, output)
  350.       DoOutputPlace(placestr, output)
  351.       if diedofstr ~= "" then do
  352.     str = "2 CAUS" diedofstr
  353.     writeln(output, str)
  354.       end
  355.     end
  356.     GETBURIALDATE i
  357.     datestr = ParseDate(RESULT)
  358.     GETBURIALPLACE i
  359.     placestr = RESULT
  360.     if datestr ~= "" | placestr ~= "" then do
  361.       writeln(output, "1 BURI")
  362.       DoOutputDate(datestr, output)
  363.       DoOutputPlace(placestr, output)
  364.     end
  365.     GETOCCUPATION i
  366.     rs1 = RESULT
  367.     if rs1 ~= "" then do
  368.       str = "1 OCCU" rs1
  369.       writeln(output, str)
  370.     end
  371.     GETEDUCATION i
  372.     rs1 = RESULT
  373.     if rs1 ~= "" then do
  374.       str = "1 EDUC" rs1
  375.       writeln(output, str)
  376.     end
  377.     GETRELIGION i
  378.     rs1 = RESULT
  379.     if rs1 ~= "" then do
  380.       str = "1 RELI" rs1
  381.       writeln(output, str)
  382.     end
  383.     comset = 0
  384.     GETPERSCOMMENT i
  385.     rs1 = RESULT
  386.     if rs1 ~= "" & rs1 ~= "[see notes]" then do
  387.       str = "1 NOTE" rs1
  388.       writeln(output, str)
  389.       comset = 1
  390.     end
  391.     if incnote then do
  392.       iname = notesdir||"PN"||i||"."||dbname
  393.       ParseCommentFile(iname, comset)
  394.     end
  395.     GETPERSREFS i
  396.     rs2 = RESULT
  397.     if rs2 ~= "" then do
  398.       str = "1 SOUR" rs2
  399.       writeln(output, str)
  400.     end
  401.     GETPARENTS i
  402.     ParFGRN = RESULT
  403.     EXISTFAMILY ParFGRN
  404.     if RESULT = 'YES' then do
  405.       str = "1 FAMC @F"ParFGRN"@"
  406.       writeln(output, str)
  407.     end
  408.     HuwNum = 0
  409.     GETMARRIAGE i HuwNum
  410.     MarrFGRN = RESULT
  411.     do while MarrFGRN ~= ""
  412.       EXISTFAMILY MarrFGRN
  413.       if RESULT = 'YES' then do
  414.         str = "1 FAMS @F"MarrFGRN"@"
  415.         writeln(output, str)
  416.       end
  417.       HuwNum = HuwNum + 1
  418.       GETMARRIAGE i HuwNum
  419.       MarrFGRN = RESULT
  420.     end
  421.   end
  422. end
  423. if ~usereq & output ~= scrdev then
  424.   Tell("Number of persons output: "||TotalIRN)
  425.   /* output to screen only if it doesn't end up
  426.    * in the middle of the GEDCOM file!
  427.    */
  428.  
  429. /* Now the list of families... */
  430.  
  431. if pgopen then Postmsg(,, "\\Processing family:\ ", PSCR)
  432.   
  433. GETTOTALFGRN
  434. TotalFGRN = Result
  435. do i = 1 to TotalFGRN
  436.   if pgopen then Postmsg(,, "\\\"||i||" (of "||TotalFGRN||")", PSCR)
  437.   EXISTFAMILY i
  438.   if RESULT = 'YES' then do
  439.     str = "0 @F"i"@ FAM"
  440.     writeln(output, str)
  441.     GETPRINCIPAL i
  442.     husb = RESULT
  443.     if husb ~= "" then do
  444.       EXISTPERSON husb
  445.       if RESULT = 'YES' then do
  446.     GETSEX husb
  447.     hsx = RESULT
  448.     /* Note: GEDCOM requires 1 husband (male) and 1 wife (female).
  449.      * Scion allows more unconventional matings as well, so we have
  450.      * to improvise a bit here, and hope the receiving program isn't
  451.      * too strict...
  452.      */
  453.     if hsx = "M" then do
  454.       str = "1 HUSB @I"husb"@"
  455.       writeln(output, str)
  456.       GETSPOUSE i
  457.       wife = RESULT
  458.       if wife ~= "" then do
  459.         EXISTPERSON wife
  460.         if RESULT = 'YES' then do
  461.           /* The principal is male; assume the partner is female */
  462.           str = "1 WIFE @I"wife"@"
  463.           writeln(output, str)
  464.         end
  465.       end    
  466.     end
  467.     else do
  468.       /* The principal isn't male - define the partner as male
  469.          and the principal as female
  470.        */
  471.       if hsx ~= "F" then do
  472.             if usereq then
  473.           rtezrequest('WARNING: Unrecognized Sex for Principal'||NL||,
  474.                 'Sex was:'||hsx||'. Assuming FEMALE!','_Continue','Converter Message:','rt_pubscrname = '||PSCR)
  475.             else
  476.           Tell("WARNING: Unrecognized Sex for Principal ("||hsx||") - assuming FEMALE")
  477.       end
  478.       GETSPOUSE i
  479.       wife = RESULT
  480.       if wife ~= "" then do
  481.         EXISTPERSON wife
  482.         if RESULT = 'YES' then do
  483.           GETSEX wife
  484.           hsx = RESULT
  485.           if hsx ~= "M" then do
  486.             if usereq then
  487.               rtezrequest('WARNING: No male partner in family!','_Continue','Converter Message:','rt_pubscrname = '||PSCR)
  488.                 else
  489.           Tell("WARNING: No male partner in family!")
  490.               end
  491.           str = "1 HUSB @I"wife"@"
  492.           writeln(output, str)
  493.         end
  494.       end
  495.       str = "1 WIFE @I"husb"@"
  496.       writeln(output, str)
  497.     end
  498.       end
  499.     end
  500.     GETENGAGEDATE i
  501.     datestr = ParseDate(RESULT)
  502.     GETENGAGEPLACE i
  503.     placestr = RESULT
  504.     if datestr ~= "" | placestr ~= "" then do
  505.       writeln(output, "1 ENGA")
  506.       DoOutputDate(datestr, output)
  507.       DoOutputPlace(placestr, output)
  508.     end
  509.     datestr = ""; placestr = ""
  510.     GETMARRYDATE i
  511.     datestr = ParseDate(RESULT)
  512.     GETMARRYPLACE i
  513.     placestr = RESULT
  514.     GETCELEBRANT i
  515.     clbrnt = RESULT
  516.     GETWITNESS i
  517.     wtness = RESULT
  518.     if datestr ~= "" | placestr ~= "" | clbrnt ~= "" | wtness ~= "" then do
  519.       writeln(output, "1 MARR")
  520.       DoOutputDate(datestr, output)
  521.       DoOutputPlace(placestr, output)
  522.       if clbrnt ~= "" then do
  523.     str = "2 OFFI" clbrnt
  524.     writeln(output, str)
  525.       end
  526.       if wtness ~= "" then do
  527.     str = "2 WITN" clbrnt
  528.     writeln(output, str)
  529.       end
  530.       /* Note that OFFI and WITN in this context are not official GEDCOM 5.3,
  531.        * but at least this way, they won't get lost when we export Scion data
  532.        * and then import the exported file again.
  533.        */
  534.     end
  535.     GETENDING i
  536.     endstr = RESULT
  537.     if endstr >= 1 & endstr <= 5 then do
  538.       /* DIV N is used eg. by PAF 2.2. It's not official GEDCOM 5.3, but I
  539.        * hope other programs can recognize it and are not confused by it.
  540.        */
  541.       if endstr = 1 then
  542.         writeln(output, "1 DIV N")
  543.       else if endstr = 2 then do
  544.         writeln(output, "1 DIV")
  545.         writeln(output, "2 TYPE DIVORCE")
  546.       end
  547.       else if endstr = 3 then do
  548.         writeln(output, "1 DIV")
  549.         writeln(output, "2 TYPE SEPARATED")
  550.       end
  551.       else if endstr = 4 then
  552.         writeln(output, "1 ANUL")
  553.       else if endstr = 5 then do
  554.         writeln(output, "1 DIV N")
  555.         writeln(output, "2 TYPE DEATH")
  556.     /* I hope this doesn't confuse other programs too much !?! */
  557.     /* This is just a temporary solution, until I find a better way */
  558.       end
  559.       datestr = ""; placestr = ""
  560.       GETENDDATE i
  561.       datestr = ParseDate(RESULT)
  562.       DoOutputDate(datestr, output)
  563.       GETENDPLACE i
  564.       placestr = RESULT
  565.       DoOutputPlace(placestr, output)
  566.     end
  567.     comset = 0
  568.     GETFAMCOMMENT i
  569.     rs1 = RESULT
  570.     if rs1 ~= "" & rs1 ~= "[see notes]" then do
  571.       str = "1 NOTE" rs1
  572.       writeln(output, str)
  573.       comset = 1
  574.     end
  575.     if incnote then do
  576.       fname = notesdir||"FN"||i||"."||dbname
  577.       ParseCommentFile(fname, comset)
  578.     end
  579.  
  580.     GETFAMREFS i
  581.     rs2 = RESULT
  582.     if rs2 ~= "" then do
  583.       str = "1 SOUR" rs2
  584.       writeln(output, str)
  585.     end
  586.  
  587.     ChNum = 0
  588.     GETCHILD i ChNum
  589.     ChIRN = RESULT
  590.     do while ChIRN ~= ""
  591.       EXISTPERSON ChIRN
  592.       if RESULT = 'YES' then do
  593.         str = "1 CHIL @I"ChIRN"@"
  594.         writeln(output, str)
  595.       end
  596.       ChNum = ChNum + 1
  597.       GETCHILD i ChNum
  598.       ChIRN = RESULT
  599.     end
  600.     /* optional:
  601.        str = "1 NCHI" ChNum
  602.        writeln(output, str)
  603.      */
  604.   end
  605. end
  606. writeln(output, "0 TRLR")
  607.  
  608. if usereq then
  609.   EndString('Conversion done.'||NL||'Number of persons output: '||TotalIRN||,
  610.     NL||'Number of families output: '||TotalFGRN||NL)
  611. else do
  612.   if output = scrdev then
  613.     Tell("Number of persons output: "||TotalIRN)
  614.   EndString("Number of families output: "||TotalFGRN)
  615. end
  616.  
  617. EXIT
  618.  
  619. /*
  620.  * Read external comment files and output to the GEDCOM file
  621.  */
  622. ParseCommentFile: PROCEDURE EXPOSE output
  623. parse arg iname,coms
  624. if ~open(infile, iname, "r") then
  625.   return 0
  626. do while ~eof(infile)
  627.   cline = GetNextCLine(infile)
  628.   if cline ~= "" | ~eof(infile) then do
  629.     if coms then
  630.       str = "2 CONT "||cline
  631.     else do
  632.       str = "1 NOTE "||cline
  633.       coms = 1
  634.     end
  635.     writeln(output, str)
  636.   end  
  637. end
  638. close(infile)
  639. return 0
  640.  
  641. /* read a line from a file; skip empty lines */
  642. GetNextCLine: PROCEDURE
  643. parse arg infile
  644. ignl = ""
  645. if ~eof(infile) then
  646.   ignl = readln(infile)
  647.   /* ignl = strip(ignl, 'b', ' '); * should we remove extra spaces? No! */
  648. return ignl
  649.  
  650. ParseDate: PROCEDURE
  651. parse arg datestr
  652.  
  653. /* optional: remove leading zero's */
  654. /* replace all ".", "-" or "/" in the date by " " */
  655. datestr = upper(translate(datestr,'   ','-./'))
  656. /* replace ABOUT by ABT, BEFORE by BEF and AFTER by AFT */
  657. if left(datestr, 5) = "ABOUT" then
  658.   datestr = "ABT"||right(datestr,length(datestr)-5)
  659. else if left(datestr, 6) = "BEFORE" then
  660.   datestr = "BEF"||right(datestr,length(datestr)-6)
  661. else if left(datestr, 5) = "AFTER" then
  662.   datestr = "AFT"||right(datestr,length(datestr)-5)
  663. return datestr
  664.  
  665. DoOutputDate: PROCEDURE
  666. parse arg datestr, output
  667. if datestr ~= "" then do
  668.   qy = right(datestr,1)
  669.   if qy="?" then
  670.     datestr = left(datestr, length(datestr)-1)
  671.   str = "2 DATE" datestr
  672.   writeln(output, str)
  673.   if qy="?" then
  674.     writeln(output, "3 QUAY 0")
  675. end
  676. return 0
  677.  
  678. DoOutputPlace: PROCEDURE
  679. parse arg placestr, output
  680. if placestr ~= "" then do
  681.   qy = right(placestr,1)
  682.   if qy="?" then
  683.     placestr = left(placestr, length(placestr)-1)
  684.   str = "2 PLAC" placestr
  685.   writeln(output, str)
  686.   if qy="?" then
  687.     writeln(output, "3 QUAY 0")
  688. end
  689. return 0
  690.  
  691. Tell: PROCEDURE EXPOSE outp scrdev
  692. parse arg str
  693. if outp then writeln(scrdev, str)
  694. return 0
  695.  
  696. TellNN: PROCEDURE EXPOSE outp scrdev
  697. parse arg str
  698. if outp then writech(scrdev, str)
  699. return 0
  700.  
  701. EndString: PROCEDURE EXPOSE outp output usereq scrdev pgopen pscr
  702. parse arg str
  703. if pgopen then Postmsg()
  704. /* If you turned off stdout, no error messages will be shown! */
  705. if usereq then
  706.   rtezrequest(str,'E_xit','Converter Message:','rt_pubscrname = '||pscr)
  707. else
  708.   Tell(str || '0A'x)
  709. if outp & ~usereq & (scrdev ~= stdout) then do
  710.   Tell("Press <return> to exit.")
  711.   readln(scrdev)
  712.   close(scrdev)
  713. end
  714. close(output)
  715. EXIT
  716.  
  717. /* Let's make sure you get a nice message when you turn off the printer :-) */
  718.  
  719. IOERR:
  720.   bline = SIGL
  721.   say "I/O error #"||RC||" detected in line "||bline||":"
  722.   say sourceline(bline)
  723.   if pgopen then Postmsg()
  724.   EXIT
  725.